/*
 * Copyright (c) 2009, Michael van der Westhuizen
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *    - Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 *    - Redistributions in binary form must reproduce the above
 *      copyright notice, this list of conditions and the following
 *      disclaimer in the documentation and/or other materials provided
 *      with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
#ifndef IMQ_IMQ_MCVDW_20090517_H
#define IMQ_IMQ_MCVDW_20090517_H

#include <Python.h>

#include <mqcrt.h>

#include <string.h>
#include <stdio.h>
#include <limits.h>

#define MQ_PLATFORM_UNKNOWN 0
#define MQ_PLATFORM_SOLARIS 1
#define MQ_PLATFORM_LINUX 2
#define MQ_PLATFORM_HPUX 3
#define MQ_PLATFORM_AIX 4
#define MQ_PLATFORM_WIN32 5
#define MQ_PLATFORM_DARWIN 6

#if 0
#define DPRINTF(x) PySys_WriteStderr x
#else
#define DPRINTF(x)
#endif


static PyObject * MQStatusError;

typedef struct {
    PyObject_HEAD
    MQStatus status;
} mqcrt_MQStatus;

typedef struct {
    PyObject_HEAD
    MQDestinationHandle destination;
    PyObject * session;
} mqcrt_MQDestination;

typedef struct {
    PyObject_HEAD
    MQMessageHandle message;
    PyObject * session;
} mqcrt_MQMessage;

typedef struct {
    PyObject_HEAD
    MQProducerHandle producer;
    int closed;
    PyObject * session;
} mqcrt_MQProducer;

typedef struct {
    PyObject_HEAD
    MQConsumerHandle consumer;
    PyObject * session;
    int closed;
    void * callback_data;
} mqcrt_MQConsumer;

typedef struct {
    PyObject_HEAD
    MQSessionHandle session;
    int closed;
    PyObject * connection;
} mqcrt_MQSession;

typedef struct {
    PyObject * connection;
    PyObject * callable;
    PyObject * args;
} connectionExceptionListenerData;

typedef struct {
    PyObject_HEAD
    MQConnectionHandle connection;
    int closed;
    int stopped;
    int xa;
    connectionExceptionListenerData * cb_data;
} mqcrt_MQConnection;

typedef struct {
    mqcrt_MQConsumer * consumer;
    PyObject * callable;
    PyObject * args;
} messageListenerData;

static MQPropertiesHandle template_properties = MQ_INVALID_HANDLE;
#define HANDLE_IS_VALID(x) ((x).handle != template_properties.handle)
#define COPY_HANDLE(dst,src) ((dst).handle = (src).handle)
#define INIT_HANDLE(x) COPY_HANDLE((x),template_properties)

#define SAFE_FREE_HANDLE(t,f,h) do { \
    t h_;                            \
    COPY_HANDLE(h_, (h));            \
    INIT_HANDLE((h));                \
    if (HANDLE_IS_VALID(h_)) {       \
        f (h_);                      \
        INIT_HANDLE(h_);             \
    }                                \
} while (0)

#define SAFE_FREE_PROPERTIES(h) SAFE_FREE_HANDLE(MQPropertiesHandle,MQFreeProperties,(h))
#define SAFE_FREE_MESSAGE(h) SAFE_FREE_HANDLE(MQMessageHandle,MQFreeMessage,(h))

#endif
